package com.gitee.cashzhang27.test.sdk.bestsign.core.util;

import static cn.hutool.crypto.asymmetric.SignAlgorithm.SHA1withRSA;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.asymmetric.AsymmetricAlgorithm;
import cn.hutool.crypto.asymmetric.Sign;
import cn.hutool.http.HttpUtil;
import cn.hutool.http.Method;
import com.google.common.collect.Maps;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import lombok.experimental.UtilityClass;

/**
 * @author Cash Zhang
 * @version v1.0
 * @since 2019/08/02 21:19
 */
@UtilityClass
public class CryptUtils {

  public String sign(String developerId,
      String privateKey,
      String host,
      String methodName,
      Method methodType,
      String rtick,
      Map<String, String> paramMap,
      String bodyOriginalJson) throws Exception {
    StringBuilder stringBuilder = new StringBuilder();
    String requestPath = new URL(host + methodName).getPath();
    HashMap<String, String> basicMap = Maps.newHashMap();
    basicMap.put("developerId", developerId);
    basicMap.put("rtick", rtick);
    basicMap.put("signType", "rsa");

    if (Method.GET.equals(methodType)) {
      paramMap.putAll(basicMap);
      paramMap = MapUtil.sort(paramMap);
      stringBuilder.append(HttpUtil.toParams(paramMap)).append(requestPath);
    } else if (Method.POST.equals(methodType)) {
      String md5BodyJson = SecureUtil.md5(bodyOriginalJson);
      paramMap = MapUtil.sort(basicMap);
      stringBuilder.append(HttpUtil.toParams(paramMap)).append(requestPath).append(md5BodyJson);
    }
    String signStr = stringBuilder.toString().replace("&", "");

    byte[] encodePrivateKey = SecureUtil
        .generatePrivateKey(AsymmetricAlgorithm.RSA.name(), Base64.decode(privateKey)).getEncoded();

    Sign sign = SecureUtil.sign(SHA1withRSA, encodePrivateKey, null);
    byte[] signBytes = sign.sign(signStr.getBytes());
    return Base64.encodeUrlSafe(signBytes);
  }

  /**
   * unix时间戳+4位随机数
   */
  public static String getRtick() {
    long timestamp = System.currentTimeMillis();
    int randomInt = RandomUtil.randomInt(1000, 10000);
    return timestamp + "" + randomInt;
  }

}
